#ifndef _CVT_H_
#define _CVT_H_
#include <vector>
using namespace std;
extern DOUBLE MAXIMUM ;

class Vertex_handle_ex: public Vertex_handle
{
public:
	Vertex_handle_ex():Vertex_handle()
	{
		validate = true;
	}
	Vertex_handle_ex( Vertex_handle & v_handle):Vertex_handle (v_handle)
	{
		validate = true;
	}
private:
	bool validate;
};

class CVT : public DT
{
public:
	typedef enum {TWO_RAY, ONE_LINE, TWO_LINE, BOUNDED} FACE_TYPE;
	
	CVT ()
	{
	}
	CVT (Polygon & bound, std::vector<Point> sites)
	{
		m_bound = bound;
		for (unsigned i = 0; i < sites.size(); ++i)
		{
			Vertex_handle v_handle= DT::insert (sites[i]);
			vertex_index.push_back(v_handle);
			
		}
		assert (DT::is_valid());
	}	
	void set_bound(Polygon & bound)
	{
		this->m_bound = bound;
	}
	unsigned insert (const Point & sites)
	{
		Vertex_handle v_handle = DT::insert (sites) ;
		assert (DT::is_valid());
		vertex_index.push_back (v_handle);
		return vertex_index.size();
		
	}
	void move (unsigned index, const Point & sites)
	{
		DT::remove (vertex_index[index]);
		Vertex_handle v_handle = DT::insert (sites);
		vertex_index[index] = v_handle;
	}
	void remove (Vertex_handle hv)
	{
		DT::remove(hv);
		assert (DT::is_valid());
	}
	
	void print_vertex_ordered()
	{
		for(unsigned i = 0; i < vertex_index.size(); ++i)
		{
			std::cout<< * vertex_index[i]<<std::endl;
		}
	}
	void print_vertex ()
	{
		for(Point_iterator hPoint  = points_begin(); 
				hPoint != points_end(); 
				hPoint++)
		{
			std::cout<< * hPoint <<std::endl;
		}
	}

	void convert_face_polygon (unsigned i, Polygon & polygon);
	
	void convert_face_region  (unsigned i, Polygon & polygon);
	unsigned size()
	{
		return vertex_index.size();
	}
protected:
	
	void convert_ray_diseg (Ray & ray, Segment & seg, Point & site, unsigned length);
	void convert_line_segment (Line & ray, Segment & s, unsigned length);
	void convert_seg_diseg (Segment & seg, Segment & result, Point & site);
	bool intersect (const Polygon & p1, const Polygon & p2, Polygon & p_result);
	Polygon m_bound;
	vector <Vertex_handle> vertex_index;
	
};


void centroid (Polygon & polygon, Point & centroid) ;
DOUBLE energy_function (std::vector<Point> & oldseeds, std::vector<Point> & newseeds) ; 
void faces_centroid (std::vector <Polygon> & faces, std::vector <Point> & centroids) ;

#endif
